package br.jus.cnj.util;

import java.text.Collator;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.text.MaskFormatter;

public class StringUtils {

	/**
	 * <p>
	 * Verifica se uma String contém espacos em branco, é vazia ("") ou nula. A String " " não será considerada como preenchida.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.isEmBranco(null)      = true
	 * StringUtils.isEmBranco("")        = true
	 * StringUtils.isEmBranco(" ")       = true
	 * StringUtils.isEmBranco("  ")      = true
	 * StringUtils.isEmBranco("cnj")     = false
	 * StringUtils.isEmBranco("  cnj  ") = false
	 * </pre>
	 * 
	 * @param value
	 *            string a ser verificada, pode ser null.
	 * @return <code>true</code> se a String é nula, vazia ou apenas com espaços
	 *         em branco
	 */
	public static boolean isEmBranco(String value) {
		return org.apache.commons.lang.StringUtils.isBlank(value);
	}
	
	/**
	 * <p>
	 * Verifica se uma String é nula ou não está preenchida com nenhum caracter. A String " " será considerada como preenchida.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.isVazia(null)      = true
	 * StringUtils.isVazia("")        = true
	 * StringUtils.isVazia(" ")       = false
	 * StringUtils.isVazia("  ")      = false
	 * StringUtils.isVazia("cnj")     = false
	 * StringUtils.isVazia("  cnj  ") = false
	 * </pre>
	 * 
	 * @param value
	 *            string a ser verificada, pode ser null.
	 * @return <code>true</code> se a String é null ou sem nenhum caracter(A String " " será considerada como preenchida).
	 */
	public static boolean isVazia(String value) {
		return org.apache.commons.lang.StringUtils.isEmpty(value);
	}
	
	/**
	 * <p>
	 * Compara duas Strings ignorando case e acentuação das Strings passadas.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.comparaIgnorandoCaseEAcentuacao(null,null)      != 0
	 * StringUtils.comparaIgnorandoCaseEAcentuacao(null,"")        != 0
	 * StringUtils.comparaIgnorandoCaseEAcentuacao("Acentuação","acentuacao") == 0
	 * StringUtils.comparaIgnorandoCaseEAcentuacao("Acentuação","Acentuação") == 0
	 * </pre>
	 * 
	 * @param string1
	 *            string a ser verificada, pode ser null porém sempre retornará false.
	 * @param string2
	 *            string a ser verificada, pode ser null porém sempre retornará false.
	 * @return <code>0</code> se as Strings comparadas são iguais ignorando case e acentuação
	 */
	public static int comparaIgnorandoCaseEAcentuacao(String str1,String str2) { 
		if(str1 == null || str2 == null){
			return -1;
		}
		
		try {
			return getCollatorIgnoreCaseEAcentuacao().compare (str1, str2);
		} catch (Exception e) {
		}
		return 0;
	
	}
	
	private static Collator getCollatorIgnoreCaseEAcentuacao() { 
		 
		Collator collator = Collator.getInstance (new Locale ("pt", "BR"));  
	    collator.setStrength(Collator.PRIMARY);   
	    
	    return collator;
		
	}
	
	/**
	 * <p>
	 * Retira os caracteres especiais da String substituindo-os por caracteres padrão internacional.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.retirarCaracteresEspeciais(null)            = null
	 * StringUtils.retirarCaracteresEspeciais("Acentuação")    = "Acentuacao"
	 * StringUtils.retirarCaracteresEspeciais("Substituir")    = "Substituir"
	 * </pre>
	 * 
	 * @param string
	 *            String a ser passada, pode ser null porém sempre retornará null.
	 * @return <code>true</code> se as Strings comparadas são iguais ignorando case e acentuação
	 */
	public static String retirarCaracteresEspeciais(String s){
    	if(s == null){
    		return null;
    	}
		
		String[] original = {"á", "Á"
    			            ,"é", "É"
    			            ,"í", "Í"
    			            ,"ó", "Ó"
    			            ,"ú", "Ú"
    			            ,"ã", "Ã"
    			            ,"õ", "Õ"
    			            ,"à", "À"
    			            ,"â", "Â"
    			            ,"ê", "Ê"
    			            ,"ô", "Ô"
    			            ,"ç", "Ç"
    			            ,"ª", "º"
    			            ,"ä", "Ä"
    			            ,"ë", "Ë"
    			            ,"ï", "Ï"
    			            ,"ö", "Ö"
    			            ,"ü", "�"
    			            };
    	String[] trocarPor = {
			                 "a", "A"
				            ,"e", "E"
				            ,"i", "I"
				            ,"o", "O"
				            ,"u", "U"
				            ,"a", "A"
				            ,"o", "O"
				            ,"a", "A"
    			            ,"a", "A"
    			            ,"e", "E"
    			            ,"o", "O"
				            ,"c", "C"
    			            ,"a", "o"
			                ,"a", "A"
				            ,"e", "E"
				            ,"i", "I"
				            ,"o", "O"
				            ,"u", "U"
        };

    	String retorno = new String(s);

    	for (int i = 0; i < trocarPor.length-1; i++) {
			retorno = retorno.replace(original[i], trocarPor[i]);
		}
    	return retorno;
    }
	
	/**
	 * <p>
	 * Retorna somente numeros
	 * </p>
	 * 
	 * @param str String que terá todos os caracteres removidos, retornando apenas números.
	 */
	public static String somenteNumero(String str){
		return str.replaceAll("\\D", "");
	}
	
	/**
	 * <p>
	 * Permite reduzir uma String muito grande a um número limitado de caracteres colocando ou não reticências ao final.
	 * 
	 * </p>
	 * 
	 * @param string
	 *            string qualquer
	 * @param limite
	 *            qual será o tamanho máximo da String
	 * @param reticencias
	 *            se ao final da String será colocada reticências ou não
	 * @return <code>string</code> string formatada.
	 */
	public static String limitarTamanhoString(String string,int limite,boolean reticencias){
		if(string != null && string.length() > limite){
			return string.substring(0, limite) + (reticencias ? "..." : "");
		}
		return string;
	}
	
	/**
	 * <p>
	 * Permite retornar qualquer tipo de número formatado a partir da máscara
	 * desejada. A máscara deve ser criada a partir do caractere #(tralha). Se o
	 * número informado for <code>123456789</code> e a máscara de formatação for
	 * <code>###-###.###</code>, o retorno será <code>123-456.789</code> </pre>
	 * 
	 * @param numero
	 *            valor que será formatado.
	 * @param formatoMascara
	 *            formato da mascara a qual o número será alterado.
	 * @return <code>numero</code> valor formatado.
	 */
	public static String formatarNumeroComMascara(String numero, String formatoMascara) throws Exception {
		if (!StringUtils.isEmBranco(numero)) {
			MaskFormatter mf = new MaskFormatter(formatoMascara);
			mf.setValueContainsLiteralCharacters(false);
			numero = mf.valueToString(numero);
		}
		return numero;
	}
	
	/**
	 * <p>
	 * Retorna senha MD5 a partir de um usuário e senha passados como parâmetro. A senha MD5
	 * é gerada a partir da contatenação os parâmetros de usuário e senha informados ao método.
	 * Caso algum dos parêmetros seja <code>null</code> ou <code>"" vazio</code>, será retornada uma String vazia <code>("")</code>
	 * 
	 * @param usuario
	 * @param senha
	 * @return senha MD5.
	 */
	public static String gerarSenhaMD5(String usuario, String senha) {
		if(org.apache.commons.lang.StringUtils.isBlank(usuario) || org.apache.commons.lang.StringUtils.isBlank(senha)){
			return "";
		}
		String sign = usuario + senha;

		try {
			java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
			md.update(sign.getBytes());
			byte[] hash = md.digest();
			StringBuffer hexString = new StringBuffer();
			for (int i = 0; i < hash.length; i++) {
				if ((0xff & hash[i]) < 0x10)
					hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
				else
					hexString.append(Integer.toHexString(0xFF & hash[i]));
			}
			sign = hexString.toString();
		} catch (Exception nsae) {
			nsae.printStackTrace();
		}
		return sign;
	}

	/**
	 * <p>
	 * Retorna senha MD5 a partir de uma senha passada como parâmetro.
	 * Caso algum dos parêmetros seja <code>null</code> ou <code>"" vazio</code>, será retornada uma String vazia <code>("")</code>
	 * 
	 * @param senha
	 * @return senha MD5.
	 */
	public static String gerarSenhaMD5(String senha) {
		if(org.apache.commons.lang.StringUtils.isBlank(senha)){
			return "";
		}
		try {
			java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
			md.update(senha.getBytes());
			byte[] hash = md.digest();
			StringBuffer hexString = new StringBuffer();
			for (int i = 0; i < hash.length; i++) {
				if ((0xff & hash[i]) < 0x10)
					hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
				else
					hexString.append(Integer.toHexString(0xFF & hash[i]));
			}
			senha = hexString.toString();
		} catch (Exception nsae) {
			nsae.printStackTrace();
		}
		return senha;
	}
	
	/**
	 * <p>
	 * Retorna o número de telefone com mascara, seja números de telefone com 8 ou 9 digitos.
	 * Se a String informada seja 6122222222 o retorno será <code>(61)2222-2222</code>
	 * Se a String informada seja 61222222222 o retorno será <code>(61)22222-2222</code>
	 * se algum dos parêmetros seja <code>null</code> ou <code>"" vazio</code>, será retornada uma String vazia <code>("")</code>
	 * 
	 * @param telefone ao qual será adicionada a máscara
	 * @return telefone com máscara.
	 */
	public static String aplicarMascaraTelefone(String telefone) {
		if (org.apache.commons.lang.StringUtils.isNotBlank(telefone) && telefone.length() >= 10) {
			if (telefone.length() == 10) {
				telefone = "(" + telefone.substring(0, 2) + ")" + telefone.substring(2, 6) + "-" + telefone.substring(6);
				return telefone;
			} else {
				telefone = "(" + telefone.substring(0, 2) + ")" + telefone.substring(2, 7) + "-" + telefone.substring(7);
				return telefone;
			}
		}
		return "";
	}
	
	/**
	 * <p>
	 * Verifica se um e-mail é válido.
	 * </p>
	 * 
	 * <pre>
	 * StringUtils.isEmailValido("cnj@cnj.jus.br")   = true
	 * StringUtils.isEmailValido("cnj.jus.br")       = false
	 * StringUtils.isEmailValido("cnj@cnj")          = false
	 * </pre>
	 * 
	 * @param email
	 *            string de email 
	 * @return <code>true</code> se o email for válido
	 */
	public static boolean isEmailValido(String email) {
		if(org.apache.commons.lang.StringUtils.isNotBlank(email)){
			if ( email.indexOf("@") == -1
					|| email.indexOf(".") == -1) {
				return false;
			}else{
			     //Set the email pattern string  
		         Pattern p = Pattern.compile(".+@.+\\.[a-z]+");  
			  
			     //Match the given string with the pattern  
			     Matcher m = p.matcher(email);  
			  
			     if (!m.matches())  
			       return false;  
			}
		}

		return true;
	}
}
